<template>
  <el-upload v-bind="mergedProps" v-model:file-list="internalFileList" :on-exceed="handleExceed"
    :http-request="handleHttpRequest" @success="handleSuccess" @error="handleError">
    <template #trigger>
      <!-- <el-button type="primary">选择文件</el-button> -->
      <el-icon>
        <Plus />
      </el-icon>
    </template>
    <!-- 继承所有默认插槽 -->
    <!-- <template v-for="(_, name) in $slots" #[name]="slotData">
      <slot :name="name" v-bind="slotData" />
    </template> -->
  </el-upload>
</template>

<script setup lang="ts">
import { ElMessage, ElUpload, type UploadProps, type UploadUserFile } from "element-plus";
import { Plus, } from "@element-plus/icons-vue";
import { computed, useAttrs, watch, type PropType, ref } from "vue";

const props = defineProps({
  modelValue: {
    type: Array as PropType<UploadUserFile[]>,
    default: () => [],
  },
  limit: {
    type: Number,
    default: 9,
  },
  action: {
    type: String,
    required: false,
  },
  // 自定义上传函数（覆盖默认行为）
  httpRequest: Function as PropType<UploadProps["httpRequest"]>,
});

const emit = defineEmits(["update:modelValue", "success", "error"]);

// 合并所有原生属性（自动继承el-upload参数）
const attrs = useAttrs();
const mergedProps = computed(() => ({
  ...attrs,
  fileList: props.modelValue,
  action: props.action,
  limit: props.limit,
}));

// 内部文件列表状态管理
const internalFileList = ref<UploadUserFile[]>(props.modelValue);
watch(internalFileList, (val) => {
  emit(
    "update:modelValue",
    val.map((file) => ({ ...file }))
  );
});

// 处理文件超出限制
const handleExceed: UploadProps["onExceed"] = (files) => {
  ElMessage.warning(
    `最多允许上传${props.limit}个文件，当前已选${files.length}个`
  );
};

// 自定义上传逻辑（若未覆盖则使用默认行为）
const handleHttpRequest: UploadProps["httpRequest"] = async (options) => {
  if (props.httpRequest) {
    return props.httpRequest(options);
  }
  // 默认上传逻辑（可替换为axios实例）
  const formData = new FormData();
  formData.append(options.file.name, options.file);
  try {
    const res = await fetch(options.action, {
      method: "POST",
      body: formData,
    });
    options.onSuccess?.(await res.json());
  } catch (err) {
    options.onError?.(err as any);
  }
  return { status: 200 };
};

// 成功/错误事件增强
const handleSuccess: UploadProps["onSuccess"] = (response, file, fileList) => {
  emit("success", { response, file, fileList });
  emit("update:modelValue", fileList);
};

const handleError: UploadProps["onError"] = (err, file, fileList) => {
  ElMessage.error(`上传失败: ${err.message}`);
  emit("error", { err, file, fileList });
};
</script>
